package org.ims.inv.web.action.flow;

import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.ims.inv.model.flow.ModelFlowBase;
import org.ims.inv.model.flow.material.ModelFlowMaterial;
import org.ims.inv.model.project.ModelProject;
import org.ims.inv.model.project.ModelProjectMaterial;
import org.ims.inv.service.project.ServiceProject;
import org.ims.inv.service.project.ServiceProjectMaterial;
import org.springframework.beans.BeanUtils;

import cn.trymore.core.exception.ServiceException;
import cn.trymore.core.log.LogAnnotation;
import cn.trymore.core.util.UtilCollection;
import cn.trymore.core.util.UtilString;
import cn.trymore.core.web.paging.PaginationSupport;
import cn.trymore.core.web.paging.PagingBean;

/**
 * Action: 材料设置
 * 
 * @author Jeccy.Zhao
 *
 */
public class FlowMaterialAction
extends FlowBaseAction
{
	/**
	 * The LOGGER
	 */
	private static final Logger LOGGER = Logger.getLogger(FlowMaterialAction.class);
	
	/**
	 * Service of project
	 */
	private ServiceProject serviceProject;
	
	/**
	 * Service of project material
	 */
	private ServiceProjectMaterial serviceProjectMaterial;
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 材料列表页面
	 */
	public ActionForward pageFlowMaterialIndex (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			ModelFlowMaterial formEntity = (ModelFlowMaterial) form;
			
			PagingBean pagingBean = this.getPagingBean(request);
			PaginationSupport<ModelFlowMaterial> result = 
				this.serviceWorkFlow.getServiceFlowMaterial().getPagination(formEntity, pagingBean);
			
			request.setAttribute("datagrid", result);
			request.setAttribute("formEntity", formEntity);
			
			// 输出分页信息至客户端
			outWritePagination(request, pagingBean, result);
			
		} 
		catch (ServiceException e)
		{
			LOGGER.error("Exception raised when fetch data.", e);
		}
		
		
		return mapping.findForward("page.flow.material.index");
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 材料分类信息弹框
	 */
	public ActionForward dialogFlowMaterialPage (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			String entityId = request.getParameter("id");
			if (UtilString.isNotEmpty(entityId))
			{
				if (this.isObjectIdValid(entityId))
				{
					request.setAttribute("entity", this.serviceWorkFlow.getServiceFlowMaterial().get(entityId));
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("数据ID不合法!"));
				}
			}
			
			String rootId = request.getParameter("rootId");
			if (UtilString.isNotEmpty(rootId))
			{
				if (this.isObjectIdValid(rootId))
				{
					ModelFlowMaterial parent = this.serviceWorkFlow.getServiceFlowMaterial().get(rootId);
					if (parent != null)
					{
						request.setAttribute("parent", parent);
					}
					else
					{
						return ajaxPrint(response, getErrorCallback("父材料实体不存在!"));
					}
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("父材料ID不合法:" + rootId));
				}
			}
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading dialog page", e);
			return ajaxPrint(response, getErrorCallback("数据加载失败,原因:" + e.getMessage()));
		}
		
		return mapping.findForward("dialog.flow.material");
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 材料配置弹框
	 */
	public ActionForward dialogFlowMaterialConfPage (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			String rootId = request.getParameter("rootId");
			if (UtilString.isNotEmpty(rootId) && this.isObjectIdValid(rootId))
			{
				ModelFlowMaterial parent = this.serviceWorkFlow.getServiceFlowMaterial().get(rootId);
				if (parent != null)
				{
					PagingBean pagingBean = this.getPagingBean(request);
					
					ModelFlowMaterial criterion = new ModelFlowMaterial();
					criterion.setMaterialParent(parent);
					
					PaginationSupport<ModelFlowMaterial> datagrid = 
						this.serviceWorkFlow.getServiceFlowMaterial().getPagination(criterion, pagingBean);
					
					request.setAttribute("datagrid", datagrid);
					request.setAttribute("parent", parent);
					
					this.outWritePagination(request, pagingBean, datagrid);
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("数据实体不存在!"));
				}
			}
			else
			{
				return ajaxPrint(response, getErrorCallback("数据ID未给定或不合法!"));
			}
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading dialog page", e);
			return ajaxPrint(response, getErrorCallback("数据加载失败,原因:" + e.getMessage()));
		}
		
		return mapping.findForward("dialog.flow.material.conf");
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 保存材料分类
	 */
	@LogAnnotation(description="材料新增或更新, `${materialName}`",type="材料设置")
	public ActionForward actionSaveFlowMaterial (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			ModelFlowMaterial formEntity = (ModelFlowMaterial)form;
			ModelFlowMaterial entity = formEntity;
			ModelFlowMaterial rootEntity = null;
			
			boolean isActionEdit = this.isObjectIdValid(formEntity.getId());
			
			if (isActionEdit)
			{
				// 编辑
				entity = this.serviceWorkFlow.getServiceFlowMaterial().get(formEntity.getId());
				if (entity != null)
				{
					BeanUtils.copyProperties(formEntity, entity, new String[] { "materialParent", "materialChildren", "sequence" } );
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("数据实体不存在!"));
				}
			}
			else
			{
				int totalSteps = 0;
				String rootId = request.getParameter("rootId");
				if (UtilString.isNotEmpty(rootId) && this.isObjectIdValid(rootId))
				{
					rootEntity = this.serviceWorkFlow.getServiceFlowMaterial().get(rootId);
					if (rootEntity != null)
					{
						entity.setMaterialParent(rootEntity);
						rootEntity.addSubMaterial(entity);
						
						List<ModelFlowMaterial> entities = 
							this.serviceWorkFlow.getServiceFlowMaterial().getByRootMaterial(rootEntity);
						
						if (UtilCollection.isNotEmpty(entities))
						{
							totalSteps = entities.size();
						}
					}
				}
				else
				{
					totalSteps = this.serviceWorkFlow.getAvailableSeqs(null, ModelFlowBase.SRC_PROCESS_MATERIAL);
				}
				
				entity.setSequence(totalSteps + 1);
			}
			
			if (rootEntity != null)
			{
				this.serviceWorkFlow.getServiceFlowMaterial().save(rootEntity);
			}
			else
			{
				// 保存
				this.serviceWorkFlow.getServiceFlowMaterial().save(entity);
			}
			
			// 关联更新
			if (!isActionEdit)
			{
				this.serviceWorkFlow.getServiceFlowMaterial().save(entity.getMaterialParent());
				
				// 更新项目材料表
				List<ModelProject> projects = this.serviceProject.getAll();
				if (UtilCollection.isNotEmpty(projects))
				{
					for (ModelProject project : projects)
					{
						if (!project.getProjectStatus().equals(
								ModelProject.EProjectStatus.APPROVED.getValue()))
						{
							Set<ModelProjectMaterial> projectMaterials = project.getMaterials();
							if (UtilCollection.isNotEmpty(projectMaterials))
							{
								ModelProjectMaterial material = new ModelProjectMaterial();
								
								for (ModelProjectMaterial projectMaterial : projectMaterials)
								{
									if (entity.getMaterialParent() == null)
									{
										material.setMaterialParent(null);
										break;
									}
									else if (projectMaterial.getMaterialName().equals(entity.getMaterialParent().getMaterialName()))
									{
										material.setMaterialParent(projectMaterial);
										break;
									}
								}
								
								material.setMaterialName(entity.getMaterialName());
								material.setMaterialType(entity.getMaterialType());
								material.setMaterialDesc(entity.getMaterialDesc());
								material.setProjectNo(project.getProjectNo());
								material.setSequence(entity.getSequence());
								
								this.serviceProjectMaterial.save(material);
								
								if (material.getMaterialParent() != null)
								{
									material.getMaterialParent().addSubMaterial(material);
									this.serviceProjectMaterial.save(material.getMaterialParent());
								}
								
								projectMaterials.add(material);
								project.setMaterials(projectMaterials);
								
								this.serviceProject.save(project);
							}
						}
					}
				}
				
			}
			
			return ajaxPrint(response, 
					getSuccessCallback("数据保存成功.", CALLBACK_TYPE_CLOSE, CURRENT_NAVTABID, null, false));
		}
		catch (ServiceException e)
		{
			LOGGER.error("Exception raised when saving data", e);
			return ajaxPrint(response, getErrorCallback("数据操作失败,原因:" + e.getMessage()));
		}
	}
	
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 材料移除
	 */
	@LogAnnotation(description="材料删除, `${id}`",type="材料设置")
	public ActionForward actionRemoveFlowMaterial (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			String entityId = request.getParameter("id");
			if (this.isObjectIdValid(entityId))
			{
				ModelFlowMaterial entity = this.serviceWorkFlow.getServiceFlowMaterial().get(entityId);
				if (entity != null)
				{
					// un-binds relationship with parent entity
					ModelFlowMaterial parent = entity.getMaterialParent();
					if (parent != null)
					{
						Iterator<ModelFlowMaterial> itor = parent.getMaterialChildren().iterator();
						while (itor.hasNext())
						{
							ModelFlowMaterial child = itor.next();
							if (child.getId().equals(entity.getId()))
							{
								child.setMaterialParent(null);
								itor.remove();
								break;
							}
						}
					}
					
					// parent removals
					if (parent != null)
					{
						this.serviceWorkFlow.getServiceFlowMaterial().save(parent);
					}
					else
					{
						// entity removals
						this.serviceWorkFlow.getServiceFlowMaterial().remove(entity);
					}
					
					// 更新sequence序列图
					this.serviceWorkFlow.refreshMaterialSequenceMap(parent);
					
					// 更新项目材料表
					List<ModelProject> projects = this.serviceProject.getAll();
					if (UtilCollection.isNotEmpty(projects))
					{
						for (ModelProject project : projects)
						{
							if (!project.getProjectStatus().equals(
									ModelProject.EProjectStatus.APPROVED.getValue()))
							{
								Set<ModelProjectMaterial> projectMaterials = project.getMaterials();
								if (UtilCollection.isNotEmpty(projectMaterials))
								{
									Iterator<ModelProjectMaterial> itor = projectMaterials.iterator();
									while (itor.hasNext())
									{
										ModelProjectMaterial projectMaterial = itor.next();
										if (projectMaterial.getMaterialName().equals(entity.getMaterialName()))
										{
											// 父节点
											if (projectMaterial.getMetas() == null)
											{
												if (UtilCollection.isNotEmpty(projectMaterial.getMaterialChildren()))
												{
													projectMaterial.setMaterialChildren(null);
												}
												itor.remove();
												
												this.serviceProjectMaterial.remove(projectMaterial);
											}
											
											break;
										}
										else if (projectMaterial.getMaterialChildren() != null)
										{
											// 遍历子节点
											boolean isFound = false;
											Set<ModelProjectMaterial> children = projectMaterial.getMaterialChildren();
											Iterator<ModelProjectMaterial> subItor = children.iterator();
											while (subItor.hasNext())
											{
												ModelProjectMaterial child = subItor.next();
												if (!UtilCollection.isNotEmpty(child.getMetas()))
												{
													if (child.getMaterialName().equals(entity.getMaterialName()))
													{
														isFound = true;
														subItor.remove();
														
														this.serviceProjectMaterial.remove(child);
														break;
													}
												}
											}
											
											if (isFound)
											{
												projectMaterial.setMaterialChildren(children);
												break;
											}
										}
									}
									
									project.setMaterials(projectMaterials);
									
									this.serviceProject.save(project);
								}
							}
						}
					}
					
					return ajaxPrint(response, 
						getSuccessCallbackAndReloadCurrent("数据删除成功."));
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("数据实体不存在!"));
				}
			}
			else
			{
				return ajaxPrint(response, getErrorCallback("数据ID不合法!"));
			}
		}
		catch (ServiceException e)
		{
			LOGGER.error("Exception raised when removing data", e);
			return ajaxPrint(response, getErrorCallback("数据删除失败,原因:" + e.getMessage()));
		}
		
	}

	public void setServiceProject(ServiceProject serviceProject)
	{
		this.serviceProject = serviceProject;
	}

	public ServiceProject getServiceProject()
	{
		return serviceProject;
	}

	public void setServiceProjectMaterial(ServiceProjectMaterial serviceProjectMaterial)
	{
		this.serviceProjectMaterial = serviceProjectMaterial;
	}

	public ServiceProjectMaterial getServiceProjectMaterial()
	{
		return serviceProjectMaterial;
	}
}
